package com.ycz.algorithm.utils.linkedlist;

/**
 * @Description
 * @ClassName LinkedListUtil
 * @Author yanchengzhi
 * @date 2024.11.14 19:17
 */
public class LinkedListUtil {

    public static void main(String[] args) {
        // 初始化链表
        ListNode n0 = initLinkedList();
        // 按照顺序遍历链表
        traversalLinkedList(n0);
        System.out.println();
        // 插入节点
        insert(n0, new ListNode(0));
        traversalLinkedList(n0);
        System.out.println();
        // 删除节点
        delete(n0);
        traversalLinkedList(n0);
        System.out.println();
        ListNode accessNode = accessNode(n0, 2);
        System.out.println("2索引位置的节点：" + accessNode.val);
        System.out.println();
        System.out.println("节点值为5的节点索引：" + findNodeIndex(n0, 5));
    }

    /**
     * @description: 初始化链表, 按照1 -> 3 -> 2 -> 5 -> 4的顺序
     * @author: yanchengzhi
     * @date: 2024/11/14 23:37
     * @param: []
     * @return: com.ycz.algorithm.utils.linkedlist.ListNode
     */
    static ListNode initLinkedList() {
        // 初始化各个节点
        ListNode n0 = new ListNode(1);
        ListNode n1 = new ListNode(3);
        ListNode n2 = new ListNode(2);
        ListNode n3 = new ListNode(5);
        ListNode n4 = new ListNode(4);
        // 构建节点间的引用
        n0.next = n1;
        n1.next = n2;
        n2.next = n3;
        n3.next = n4;
        return n0;
    }

    // 遍历链表
    static void traversalLinkedList(ListNode n0) {
        System.out.print(n0.val + "\t");
        if (n0.next != null) {
            traversalLinkedList(n0.next);
        }
    }

    /**
     * @description: 插入节点，现在在1和3之间插入0节点，形成1 -> 0 -> 3 -> 2 -> 5 -> 4的顺序
     * @author: yanchengzhi
     * @date: 2024/11/14 23:48
     * @param: [pre, insertNode]
     * @return: com.ycz.algorithm.utils.linkedlist.ListNode
     */
    static ListNode insert(ListNode pre, ListNode insertNode) {
        ListNode nex = pre.next;
        // 将前一个节点的引用指向插入节点
        pre.next = insertNode;
        // 将插入节点的引用指向后一个节点
        insertNode.next = nex;
        return pre;
    }

    /**
     * @description: 将上面添加的节点删掉，恢复链表原来的状态
     * 即删除 1 -> 0 -> 3 -> 2 -> 5 -> 4中的0，重新成为1 -> 3 -> 2 -> 5 -> 4的顺序
     * @author: yanchengzhi
     * @date: 2024/11/14 23:55
     * @param: [n0]
     * @return: com.ycz.algorithm.utils.linkedlist.ListNode
     */
    static ListNode delete(ListNode n0) {
        if (n0.next == null) return null;
        // 待删除节点
        ListNode n1 = n0.next;
        // 待删除节点的后一个节点
        ListNode n2 = n1.next;
        // 将待删除节点的前一个节点的引用设置成待删除节点的后一个节点即可完成删除
        n0.next = n2;
        return n0;
    }

    /*
     * @author yancz
     * @description 访问链表中的节点，需要从头节点开始，一个个往后找
     * 1 -> 3 -> 2 -> 5 -> 4 假如现在需要访问2这个节点
     * @date 2024/11/15 10:07
     * @param head 头节点
     * @param index 需要访问的节点索引，从0开始
     * @return ListNode 需要访问的节点
     **/
    static ListNode accessNode(ListNode head, int index) {
        if (head == null) return null;
        for (int i = 0; i < index; i++) {
            head = head.next;
        }
        return head;
    }

    /*
     * @author yancz
     * @description 查找节点
     * 遍历链表，查找其中值为 target 的节点，输出该节点在链表中的索引
     * @date 2024/11/15 14:08
     * @param head 头节点
     * @param target 需要查找节点的值
     * @return int 需要查找节点的索引
     **/
    static int findNodeIndex(ListNode head, int target) {
        int index = 0;
        while (head != null) {
            if (head.val == target) {
                return index;
            }
            head = head.next;
            index++;
        }
        return -1;
    }


}
